package com.kehutong.wwin.service.service;

import java.util.ArrayList;
import java.util.List;

import com.kehutong.wwin.service.entity.Corp;
import org.coraframework.authz.Subject;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.util.IDGenerate;
import org.coraframework.util.Objects;

import com.kehutong.common.entity.Root;
import com.kehutong.common.util.Token;
import com.kehutong.wwin.service.entity.TagMap;
import com.kehutong.wwin.service.util.WwInHttpClient;
import com.kehutong.wxapi.request.CorpTagListRequest;
import com.kehutong.wxapi.response.CorpTagListResponse;
import com.kehutong.wxapi.service.ExternalContactService;

/**
 * @author: liukunlong
 * @date: 2021-03-11 16:05
 */
@WebService("/wwin/event/change_external_tag")
public class ToKhtTagService {
    
	static final Logger logger = LoggerFactory.getLogger(ToKhtDepartmentService.class);

    @Inject
    private WwInHttpClient httpClient;

    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private ExternalContactService externalContactService;

    /**
     * 收到企业客户标签创建事件后添加标签
     * 企业/管理员创建客户标签/标签组时，回调此事件。收到该事件后，企业需要调用获取企业标签库来获取标签/标签组的详细信息。
     * @param wwJson 微信事件Json对象
     * @return 结果对象
     * @throws Exception 异常
     */
    @ReqMapping("/create")
    public Object create(JSONObject wwJson) throws Exception {
        String cropId=wwJson.getString("ToUserName");
        Corp crop = Pool.get(Corp.class, cropId);
        if (Objects.isNull(crop)) {
            logger.error("公司内建信息不存在,{}",wwJson);
            return Result.success();
        }
        //创建标签时，此项为tag，创建标签组时，此项为tag_group
        String tagType = wwJson.getString("TagType");
        String id = wwJson.getString("Id");
        Token token=Token.create();
        token.setCompanyNo(crop.getKhtid());
        return syncTag(token,tagType,id);
    }

    /**
     * 收到企业客户标签变更事件后更新标签
     * 当企业客户标签/标签组被修改时，回调此事件。收到该事件后，企业需要调用获取企业标签库来获取标签/标签组的详细信息。
     * @param wwJson 微信事件Json对象
     * @return 结果对象
     * @throws Exception 异常
     */
    @ReqMapping("/update")
    public Object update(JSONObject wwJson) throws Exception {
        String cropId=wwJson.getString("ToUserName");
        Corp crop = Pool.get(Corp.class, cropId);
        if (Objects.isNull(crop)) {
            logger.error("公司内建信息不存在,{}",wwJson);
            return Result.success();
        }
        String tagType = wwJson.getString("TagType");
        String id = wwJson.getString("Id");
        Token token=Token.create();
        token.setCompanyNo(crop.getKhtid());
        return syncTag(token,tagType,id);
    }

    /**
     * 收到企业客户标签删除事件后删除标签
     * 当企业客户标签/标签组被删除改时，回调此事件。删除标签组时，该标签组下的所有标签将被同时删除，但不会进行回调。
     * @param token  用户嘻嘻
     * @param wwJson 微信事件Json对象
     * @return 结果对象
     * @throws Exception 异常
     */
    @ReqMapping("/delete")
    public Object delete(Token token, JSONObject wwJson) throws Exception {
        return Result.success();
    }

    /**
     * 全量同步标签
     * @param token 用户信息
     * @return 结果对象
     * @throws Exception 异常
     */
    public Object syncTag(Token token) throws Exception {
        return syncTag(token,null,null);
    }

    /**
     * 同步标签（支持全部标签组同步，和单个组同步）
     * @param token 用户信息
     * @param tagType 标签类型 tag为标签，tag_group为标签组
     * @param id 微信标签id
     * @return
     * @throws Exception
     */
    public Object syncTag(Token token,String tagType,String id) throws Exception {
        CorpTagListRequest corpTagListRequest=new CorpTagListRequest();
        corpTagListRequest.setAccessToken(httpClient.getContactAccessToken(token));
        ThreadLocalCache.current().setCorpId(token.getCompanyNo());
        //标签类型 tag为标签，tag_group为标签组
        if(Objects.nonEmpty(tagType) && Objects.nonEmpty(id)){
            if(Objects.equal("tag",tagType)){
                List<String> tagId=new ArrayList<>();
                tagId.add(id);
                corpTagListRequest.setTagId(tagId);

            }else if(Objects.equal("tag",tagType)){
                List<String> groupId=new ArrayList<>();
                groupId.add(id);
                corpTagListRequest.setGroupId(groupId);
            }
        }
        CorpTagListResponse corpTagListResponse=externalContactService.getCorpTagList(corpTagListRequest);
        if (corpTagListResponse.getErrcode() != 0) {
            return Result.error(corpTagListResponse.getErrcode(), corpTagListResponse.getErrmsg());
        }
        List<CorpTagListResponse.TagGroupDTO> tagGroupList=corpTagListResponse.getTagGroup();
        if(Objects.nonEmpty(tagGroupList)){
            for(CorpTagListResponse.TagGroupDTO tagGroup:tagGroupList){
                TagMap tagGroupMap=getTagById(tagGroup.getGroupId());
                if(Objects.isNull(tagGroupMap)){
                    //客户通标签标志
                    String groupId=toKhtId(token.getCompanyNo(),"GROUP",tagGroup.getGroupName());
                    tagGroupMap = Pool.newInstance(TagMap.class,tagGroup.getGroupId());
                    tagGroupMap.setKhtid(groupId);
                    JSONObject groupTagRs = httpClient.postKht("/crm/tag/saveTag", token, http-> {
                        http.addParam("id",groupId);
                        http.addParam("name",tagGroup.getGroupName());
                        http.addParam("pid",Root.ROOT_ID);
                        http.addParam("createBy",token.getUuid());
                        http.addParam("createName",token.getUsername());
                    });
                    int groupTagResult = groupTagRs.getIntValue("code");
                    if (groupTagResult != 200) {
                        return Result.error(groupTagResult, groupTagRs.getString("message"));
                    }
                    jdbcSession.insert(tagGroupMap);

                    //保存或者更新标签信息
                    List<CorpTagListResponse.TagGroupDTO.TagDTO> tagList=tagGroup.getTag();
                    if(Objects.nonEmpty(tagList)){
                        for(CorpTagListResponse.TagGroupDTO.TagDTO tag:tagList){
                            TagMap tagMap=getTagById(tag.getId());
                            //如果标签映射没有客户通标签则新增标签及映射,否则更新标签
                            if(Objects.isNull(tagMap)){
                                //客户通标签标志
                                String tagId=toKhtId(token.getCompanyNo(),"TAG",tag.getName());
                                tagMap = Pool.newInstance(TagMap.class,tag.getId());
                                tagMap.setKhtid(tagId);
                                JSONObject tagRs = httpClient.postKht("/crm/tag/saveTag", token, http-> {
                                    http.addParam("id",tagId);
                                    http.addParam("name",tag.getName());
                                    http.addParam("pid",groupId);
                                    http.addParam("createBy",token.getUuid());
                                    http.addParam("createName",token.getUsername());
                                });
                                int tagResult = tagRs.getIntValue("code");
                                if (tagResult != 200) {
                                    return Result.error(tagResult, tagRs.getString("message"));
                                }
                                //插入标签映射信息
                                jdbcSession.insert(tagMap);
                            }else{
                                //客户通标签标志
                                String tagId=tagMap.getKhtid();
                                JSONObject tagRs = httpClient.postKht("/crm/tag/updateTag", token, http-> {
                                    http.addParam("id",tagId);
                                    http.addParam("name",tag.getName());
                                    http.addParam("createBy",token.getUuid());
                                    http.addParam("createName",token.getUsername());
                                });
                                int tagResult = tagRs.getIntValue("code");
                                if (tagResult != 200) {
                                    return Result.error(tagResult, tagRs.getString("message"));
                                }
                            }
                        }
                    }
                }else{
                    //客户通标签标志
                    String tagGroupId=tagGroupMap.getKhtid();
                    JSONObject rs = httpClient.postKht("/crm/tag/updateTag", token, http-> {
                        http.addParam("id",tagGroupId);
                        http.addParam("name",tagGroup.getGroupName());
                        http.addParam("createBy",token.getUuid());
                        http.addParam("createName",token.getUsername());
                    });
                    int result = rs.getIntValue("code");
                    if (result != 200) {
                        return Result.error(result, rs.getString("message"));
                    }

                    //保存或者更新标签信息
                    List<CorpTagListResponse.TagGroupDTO.TagDTO> tagList=tagGroup.getTag();
                    if(Objects.nonEmpty(tagList)){
                        for(CorpTagListResponse.TagGroupDTO.TagDTO tag:tagList){
                            TagMap tagMap=getTagById(tag.getId());
                            //如果标签映射没有客户通标签则新增标签及映射,否则更新标签
                            if(Objects.isNull(tagMap)){
                                //客户通标签标志
                                String tagId=toKhtId(token.getCompanyNo(),"TAG",tag.getName());
                                tagMap = Pool.newInstance(TagMap.class,tag.getId());
                                tagMap.setKhtid(tagId);
                                JSONObject tagRs = httpClient.postKht("/crm/tag/saveTag", token, http-> {
                                    http.addParam("id",tagId);
                                    http.addParam("name",tag.getName());
                                    http.addParam("pid",tagGroupId);
                                    http.addParam("createBy",token.getUuid());
                                    http.addParam("createName",token.getUsername());
                                });
                                int tagResult = tagRs.getIntValue("code");
                                if (tagResult != 200) {
                                    return Result.error(tagResult, tagRs.getString("message"));
                                }
                                //插入标签映射信息
                                jdbcSession.insert(tagMap);
                            }else{
                                //客户通标签标志
                                String tagId=tagMap.getKhtid();
                                JSONObject tagRs = httpClient.postKht("/crm/tag/updateTag", token, http-> {
                                    http.addParam("id",tagId);
                                    http.addParam("name",tag.getName());
                                    http.addParam("createBy",token.getUuid());
                                    http.addParam("createName",token.getUsername());
                                });
                                int tagResult = tagRs.getIntValue("code");
                                if (tagResult != 200) {
                                    return Result.error(tagResult, tagRs.getString("message"));
                                }
                            }
                        }
                    }

                }
            }
        }
        return Result.success();
    }

    /**
     * 根据微信标志获取映射信息
     *
     * @param id 微信标志
     * @return 映射信息
     */
    public TagMap getTagById(String id) {
        return Pool.get(TagMap.class, id);
    }

    /**
     * 构建客户映射对象
     *
     * @param wwJson 微信事件Json对象
     * @return 客户映射对象
     */
    TagMap buildTag(JSONObject wwJson) {
        TagMap customerMap = Pool.newInstance(TagMap.class, wwJson.getString("ExternalUserID"));
        customerMap.setKhtid(IDGenerate.uuid());
        return customerMap;
    }


    /**
     * 根据规则产生第三方标签标志
     * @param corpNo
     * @param type
     * @param name
     * @return
     */
    public static String toKhtId(String corpNo,String type,String name) {
        String thirdPartySource="1";
        StringBuilder buf = new StringBuilder(corpNo).append("_")
                .append(thirdPartySource).append("_")
                .append(type).append("_")
                .append(name.toUpperCase());
        return Subject.encrypt(buf.toString());
    }
}
